/**
 *******************************************************************************
 * @author      Ashwin Vijayakumar
 *
 * @file        MorseCode.c
 *
 * @date	Sep 9, 2012 10:26:35 AM
 *******************************************************************************
 * @copyright 2012
 * <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/>Creative Commons by-nc-sa</a>
 * by <a href="http://www.afflatustech.com">Afflatus Techtronics</a>
 * and <a href="http://www.ashwinvijayakumar.co.nr">Ashwin Vijayakumar</a>
 *******************************************************************************
 */

/**@cond -----------------------------------------------------------------------
 * Includes section
 * ----------------------------------------------------------------- @endcond */

/**@cond System headers -------------------------------------------- @endcond */
#include <htc.h>

/**@cond Local headers --------------------------------------------- @endcond */
#include "MorseCode.h"


/**@cond -----------------------------------------------------------------------
 * Macros section (File scope)
 * ----------------------------------------------------------------- @endcond */

/**
 * @brief Delay loop for Morse Code
 * @warning This is a blocking function call
 */
#define MorseCode_Delay(delay_counter)                  \
    do                                                  \
    {                                                   \
        int i;                                          \
        for( i = 0; i < delay_counter; i++ );           \
    }while(0)

/**@cond -----------------------------------------------------------------------
 * Global variables section (Project scope)
 * ----------------------------------------------------------------- @endcond */
#if 0
const int MorseCode_Map[258] = {
    /* Width, DOT/DASH, DOT/DASH ... */
    /* '0' */
    5, 1, 1, 1, 1, 1,
    /* '1' */
    5, 0, 1, 1, 1, 1,
    /* '2' */
    5, 0, 0, 1, 1, 1,
    /* '3' */
    5, 0, 0, 0, 1, 1,
    /* '4' */
    5, 0, 0, 0, 0, 1,
    /* '5' */
    5, 0, 0, 0, 0, 0,
    /* '6' */
    5, 1, 0, 0, 0, 0,
    /* '7' */
    5, 1, 1, 0, 0, 0,
    /* '8' */
    5, 1, 1, 1, 0, 0,
    /* '9' */
    5, 1, 1, 1, 1, 0,
    /* ':' */
    0, 0, 0, 0, 0, 0,
    /* ';' */
    0, 0, 0, 0, 0, 0,
    /* '<' */
    0, 0, 0, 0, 0, 0,
    /* '=' */
    0, 0, 0, 0, 0, 0,
    /* '>' */
    0, 0, 0, 0, 0, 0,
    /* '?' */
    0, 0, 0, 0, 0, 0,
    /* '@' */
    0, 0, 0, 0, 0, 0,
    /* 'A' */
    2, 0, 1, 0, 0, 0,
    /* 'B' */
    4, 1, 0, 0, 0, 0,
    /* 'C' */
    4, 1, 0, 1, 0, 0,
    /* 'D' */
    3, 1, 0, 0, 0, 0,
    /* 'E' */
    1, 0, 0, 0, 0, 0,
    /* 'F' */
    4, 0, 0, 1, 0, 0,
    /* 'G' */
    3, 1, 1, 0, 0, 0,
    /* 'H' */
    4, 0, 0, 0, 0, 0,
    /* 'I' */
    2, 0, 0, 0, 0, 0,
    /* 'J' */
    4, 0, 1, 1, 1, 0,
    /* 'K' */
    3, 1, 0, 1, 0, 0,
    /* 'L' */
    4, 0, 1, 0, 0, 0,
    /* 'M' */
    2, 1, 1, 0, 0, 0,
    /* 'N' */
    2, 1, 0, 0, 0, 0,
    /* 'O' */
    3, 1, 1, 1, 0, 0,
    /* 'P' */
    4, 0, 1, 1, 0, 0,
    /* 'Q' */
    4, 1, 1, 0, 1, 0,
    /* 'R' */
    3, 0, 1, 0, 0, 0,
    /* 'S' */
    3, 0, 0, 0, 0, 0,
    /* 'T' */
    1, 1, 0, 0, 0, 0,
    /* 'U' */
    3, 0, 0, 1, 0, 0,
    /* 'V' */
    4, 0, 0, 0, 1, 0,
    /* 'W' */
    3, 0, 1, 1, 0, 0,
    /* 'X' */
    4, 1, 0, 0, 1, 0,
    /* 'Y' */
    4, 1, 0, 1, 1, 0,
    /* 'Z' */
    4, 1, 1, 0, 0, 0
};
#endif

const int MorseCode_Map[37] = {
    /* Width, DOT/DASH, DOT/DASH ... */
    /* 'H' */
    4, 0, 0, 0, 0, 0,
    /* 'E' */
    1, 0, 0, 0, 0, 0,
    /* 'A' */
    2, 0, 1, 0, 0, 0,
    /* 'R' */
    3, 0, 1, 0, 0, 0,
    /* 'T' */
    1, 1, 0, 0, 0, 0,
    /* 'B' */
    4, 1, 0, 0, 0, 0
};

/**
 *******************************************************************************
 * @fn          static void MorseCode_Dot( void )
 * @return      none
 * @param       none
 * @brief       Asserts MORSE_CODE_PIN for DOT duration
 * @warning     This is a blocking function call
 *******************************************************************************
 */

static void
MorseCode_Dot( void )
{
  MORSE_CODE_PIN = 0;
  MorseCode_Delay( MORSE_DOT_DELAY );
  MORSE_CODE_PIN = 1;
}

/**
 *******************************************************************************
 * @fn          static void MorseCode_Dash( void )
 * @return      none
 * @param       none
 * @brief       Asserts MORSE_CODE_PIN for DASH duration
 * @warning     This is a blocking function call
 *******************************************************************************
 */

static void
MorseCode_Dash( void )
{
  MORSE_CODE_PIN = 0;
  MorseCode_Delay( MORSE_DASH_DELAY );
  MORSE_CODE_PIN = 1;
}

/**
 *******************************************************************************
 * @fn          static void MorseCode_Putc( char character )
 * @return      none
 * @param       char character: ASCII character to be transmitted as morse code
 * @brief       Outputs the specified character on MORSE_CODE_PIN
 *******************************************************************************
 */

void
MorseCode_Putc( char character )
{
  int i;
  int pCodeIndex = ((( character - '0') * 5) + ( character - '0'));
  int elementLen = MorseCode_Map[pCodeIndex];

  for( i = 0; i < elementLen; i++ )
    {
      if( !MorseCode_Map[++pCodeIndex] )
        {
          MorseCode_Dot();
          MorseCode_Delay( MORSE_ELEMENT_DELAY );
        }
      else
        {
          MorseCode_Dash();
          MorseCode_Delay( MORSE_ELEMENT_DELAY );
        }
    }
}

/**
 *******************************************************************************
 * @fn          static void MorseCode_Puts( char* pChar )
 * @return      none
 * @param       char* pChar: Pointer to a null terminated string which needs to
 *              be transmitted as morse code.
 * @brief       Outputs the NULL terminated string on MORSE_CODE_PIN
 *******************************************************************************
 */

void
MorseCode_Puts( char* pChar )
{
  while( *pChar )
    {
      MorseCode_Putc( *pChar++ );
      MorseCode_Delay( MORSE_WORD_DELAY );
    }
}

/** END OF FILE ********************* Copyright (C) 2012 Afflatus Techtronics */
